package com.hoapital.outpbillwork.module.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hoapital.outpbillwork.module.entity.*;
import com.hoapital.outpbillwork.module.mapper.*;
import com.hoapital.outpbillwork.module.service.DrugPrescMasterService;
import com.hospital.common.core.constants.OrderConstant;
import com.hospital.common.core.exception.ExceptionHelp;
import com.hospital.common.core.exception.ExceptionHelpEnum;
import com.hospital.common.core.function.PushMessage;
import com.hospital.common.core.module.controller.dto.BillDto;
import com.hospital.common.core.module.controller.dto.ClinicItem;
import com.hospital.common.core.module.controller.dto.ClinicType;
import com.hospital.common.core.module.controller.vo.Receive;
import com.hospital.common.core.module.controller.vo.ReceiveDate;
import com.hospital.common.core.result.ErrorTip;
import com.hospital.common.core.result.SuccessTip;
import com.hospital.common.core.result.Tip;
import com.hospital.common.core.utils.DateUtil;
import com.hospital.common.core.utils.StrKit;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author lvyao
 * @since 2021-03-31
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class DrugPrescMasterServiceImpl extends ServiceImpl<DrugPrescMasterMapper, DrugPrescMaster> implements DrugPrescMasterService {

    @Resource
    private DrugPrescMasterMapper drugPrescMasterMapper;

    @Resource
    private DrugPrescDetailMapper drugPrescDetailMapper;

    @Resource
    private ClinicVsChargeMapper clinicVsChargeMapper;

    @Resource
    private OutpOrderDescMapper outpOrderDescMapper;

    @Resource
    private OutpOrderDescTempMapper outpOrderDescTempMapper;

    @Resource
    private OutpDoctorPrescMasterMapper outpDoctorPrescMasterMapper;

    @Resource
    private OutpDoctorPrescItemsMapper outpDoctorPrescItemsMapper;

    @Resource
    private OutpBillItemsTempMapper outpBillItemsTempMapper;

    @Resource
    private OutpDoctorAssistantMapper outpDoctorAssistantMapper;

    @Resource
    private PatientInfoMapper patientInfoMapper;

    @Resource
    private PushMessage pushMessage;

    @Override
    public boolean updateChargeFlag(String visitDate, String visitNo) {
        return drugPrescMasterMapper.updateChargeFlag(visitDate, visitNo);
    }

    @Override
    public int updatePrescStatus(String visitDate, String visitNo, String enterBy, String billDateTime, String prescStatus) {
        return drugPrescMasterMapper.updatePrescStatus(visitDate, visitNo, enterBy, billDateTime, prescStatus);
    }

    @Override
    public DrugPrescMaster getDrugPrescmaster(String visitDate, String visitNo) {
        return drugPrescMasterMapper.getDrugPrescmaster(visitDate, visitNo);
    }


    @Override
    public boolean savePrescBill(Receive receive) {
        List<DrugPrescDetail> drugPrescDetailList = drugPrescDetailMapper.getPrescDetail(receive.getPrimaryDate(), receive.getPrimaryNo());
        DrugPrescMaster drugPrescmaster = drugPrescMasterMapper.getDrugPrescmaster(receive.getPrimaryDate(), receive.getPrimaryNo());
        List<ReceiveDate> receiveDateList = receive.getData();
        if (receiveDateList != null && !receiveDateList.isEmpty() && drugPrescDetailList.size() == receiveDateList.size()) {
            //更新医嘱处方表中计费标记
            if (!drugPrescMasterMapper.updateChargeFlag(receive.getPrimaryDate(), receive.getPrimaryNo())) {
                throw new ExceptionHelp(ExceptionHelpEnum.UPDATE_OUTP_PRESC);
            }
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
            //更新药品处方表中处方标记
            if (drugPrescMasterMapper.updatePrescStatus(receive.getPrimaryDate(), receive.getPrimaryNo(), "0000", simpleDateFormat.format(new Date()), "计费") <= 0) {
                throw new ExceptionHelp(ExceptionHelpEnum.UPDATE_OUTP_DRUG_PRESC);
            }
            //处理门诊医嘱主表，删除门诊医嘱临时表，删除门诊计费临时表，插入住院计费，插入门诊计费表
            boolean commBill = commBill(receive, drugPrescmaster.getPatientId(), String.valueOf(drugPrescmaster.getVisitId()), drugPrescmaster.getOrderedBy());
            if (!commBill) {
                throw new ExceptionHelp(ExceptionHelpEnum.COMMBILL);
            }
            return true;
        } else {
            throw new ExceptionHelp(ExceptionHelpEnum.RECEIVE_DATE);
        }
    }

    @Override
    public boolean commBill(Receive receive, String patientId, String visitId, String orderedBy) {
        List<ReceiveDate> receiveDateList = receive.getData();
        if (receiveDateList != null && !receiveDateList.isEmpty()) {
            //组装收费信息模板计费
            BillDto billDto = new BillDto();
            billDto.setOutpId(receive.getOutpOrInp());
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
            Date visitDate = null;
            billDto.setVisitNo(receive.getPrimaryNo());
            try {
                visitDate = simpleDateFormat.parse(receive.getPrimaryDate());
            } catch (ParseException e) {
                e.printStackTrace();
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                throw new ExceptionHelp(ExceptionHelpEnum.FILED_TRANS_DATEFORMAT);
            }
            billDto.setVisitDate(visitDate);
            List<ClinicType> clinicTypeList = new ArrayList<>();
            ClinicType clinicType = new ClinicType();
            clinicType.setType(receive.getTaskId());
            List<ClinicItem> clinicItemList = new ArrayList<>();
            for (ReceiveDate receiveDate : receiveDateList) {
                List<ClinicVsCharge> clinicVsChargeList = clinicVsChargeMapper.getOrderItemBillDetail(receive.getTaskId(), receiveDate.getItemCode());
                if (clinicVsChargeList != null && clinicVsChargeList.size() > 0) {
                    ClinicItem clinicItem = new ClinicItem();
                    clinicItem.setClinicItemCode(receiveDate.getItemCode());
                    clinicItem.setPerformedBy(receiveDate.getPerformedDept());
                    clinicItem.setOrderedBy(orderedBy);
                    clinicItem.setPrimaryDate(receive.getPrimaryDate());
                    clinicItem.setPrimaryNo(receive.getPrimaryNo());
                    clinicItem.setOperatorNo(receiveDate.getOperator());
                    //删除单个收费项目收费临时表中数据门诊删除
                    List<String> deleteBillItemList = new ArrayList<>();
                    for (ClinicVsCharge clinicVsCharge : clinicVsChargeList) {
                        deleteBillItemList.add(clinicVsCharge.getChargeItemCode());
                    }
                    if (receive.getOutpOrInp().equals("01")) {
                        int deleteBillItems = outpBillItemsTempMapper.deleteBillItems(receive.getPrimaryDate(), receive.getPrimaryNo(), deleteBillItemList);
                        if (deleteBillItems <= 0) {
                            throw new ExceptionHelp(ExceptionHelpEnum.FILED_DELETE_BILL);
                        }
                    }
                    clinicItem.setAmount(receiveDate.getAmount());
                    clinicItemList.add(clinicItem);
                } else {
                    throw new ExceptionHelp(ExceptionHelpEnum.PRESC_BILL_ITEM);
                }
                if (outpDoctorAssistantMapper.getApplyNo(receive.getPrimaryDate(), receive.getPrimaryNo(), receiveDate.getItemCode()) != null) {
                    int updateFlag = outpDoctorAssistantMapper.updateFlag(receive.getPrimaryDate(), receive.getPrimaryNo(), receiveDate.getItemCode());
                    if (updateFlag < 0) {
                        throw new ExceptionHelp(ExceptionHelpEnum.UPDATE_OUTP_Assis);
                    }
                }
            }
            clinicType.setClinicItemList(clinicItemList);
            clinicTypeList.add(clinicType);
            billDto.setClinicTypeList(clinicTypeList);
            OutpOrderDescTemp outpOrderDescTemp = outpOrderDescTempMapper.getOrderTempDate(receive.getPrimaryDate(), receive.getPrimaryNo());
            String chargeType = null;
            if (receive.getOutpOrInp().equals("01")) {
                billDto.setPatientId(outpOrderDescTemp.getPatientId());
                billDto.setOutpId(String.valueOf(outpOrderDescTemp.getOutpId()));
                chargeType = clinicVsChargeMapper.getChargeType(outpOrderDescTemp.getPatientId(), String.valueOf(outpOrderDescTemp.getOutpId()));
            } else {
                billDto.setPatientId(patientId);
                billDto.setVisitId(String.valueOf(visitId));
                chargeType = clinicVsChargeMapper.getPatChargeType(patientId);
            }
            if (chargeType == null || chargeType.isEmpty()) {
                chargeType = "自费";
            }
            billDto.setChargeType(chargeType);
//            billDto.setOutpOrinp(receive.getOutpOrInp());
            billDto.setOutpOrInp(receive.getOutpOrInp());
            //医嘱正式表中是否有数据,以及明细收费临时表中数据是否已经删除完
            int dataOrder = outpOrderDescMapper.getDataOrder(receive.getPrimaryDate(), receive.getPrimaryNo());
            List<OutpBillItemsTemp> outpBillItemsTemp = outpBillItemsTempMapper.getOutpBillItemsTemp(receive.getPrimaryDate(), receive.getPrimaryNo());

            //无主表数据则插入医嘱主表门诊
            if (dataOrder == 0 && receive.getOutpOrInp().equals("01")) {
                //获取医嘱临时表中数据并赋值给医嘱正式表
                OutpOrderDesc outpOrderDesc = new OutpOrderDesc();
                BeanUtils.copyProperties(outpOrderDescTemp, outpOrderDesc);
                Integer insert = outpOrderDescMapper.insert(outpOrderDesc);
                if (insert <= 0) {
                    throw new ExceptionHelp(ExceptionHelpEnum.INSERT_ORDER_DESC);
                }
            }
            if ((outpBillItemsTemp == null || outpBillItemsTemp.isEmpty()) && receive.getOutpOrInp().equals("01")) {
                //费用临时表中数据若已删除完成则删除临时医嘱主表数据
                int deletTemp = outpOrderDescTempMapper.deletTemp(receive.getPrimaryDate(), receive.getPrimaryNo());
                if (deletTemp <= 0) {
                    throw new ExceptionHelp(ExceptionHelpEnum.DELETE_ORDER_DESC_TEMP);
                }
            }


            //计费接口调用
//            String jsonString = JSON.toJSONString(billDto);
//            HttpResponse execute = HttpRequest.post(outpOrderDescTempMapper.getBillUrl()).body(jsonString).execute();
//            if (execute.getStatus() != 200) {
//                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
//                throw new ExceptionHelp(ExceptionHelpEnum.FILED_REQ_BILL_SERVER);
//            }
            boolean sendBill = pushMessage.sendBillMsg(billDto, outpOrderDescTempMapper.getBillUrl());
            if (!sendBill) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                throw new ExceptionHelp(ExceptionHelpEnum.FILED_REQ_BILL_SERVER);
            }
        }
        return true;
    }

    @Override
    public Tip prescCkeck(String[] prescAttrNo) {
        String visitDate;
        String visitNo;
        String checkDept;
        String oper;
        String verifyFlag;
        String verifyRefuseCause;
        try {
            visitDate = prescAttrNo[1].substring(0, 14);
            visitNo = prescAttrNo[1].substring(14);
            verifyFlag = prescAttrNo[0];
            String[] split = prescAttrNo[4].split(":");
            checkDept = split[0];
            oper = split[1];
            int strlength = StrKit.getStrlength(prescAttrNo[5]);
            if (strlength > 2000) {
                throw new ExceptionHelp(ExceptionHelpEnum.PRESC_CHECK_REFUSE_TOOLONG);
            }
            verifyRefuseCause = prescAttrNo[5];
        } catch (Exception e) {
            throw new ExceptionHelp(ExceptionHelpEnum.PRESC_CHECK_DO_DATA);
        }
        String sql = "visit_Date = to_Date({0},'yyyy-mm-dd hh24:mi:ss') and visit_no = {1}";
        OutpDoctorPrescMaster outpDoctorPrescMaster = outpDoctorPrescMasterMapper.getOutpDocPresc(visitDate, visitNo);
        QueryWrapper<OutpDoctorPrescItems> outpDoctorPrescItemsQueryWrapper = new QueryWrapper<>();
        outpDoctorPrescItemsQueryWrapper.apply(sql, visitDate, visitNo);
        List<OutpDoctorPrescItems> outpDoctorPrescItemsList = outpDoctorPrescItemsMapper.selectList(outpDoctorPrescItemsQueryWrapper);
        if (outpDoctorPrescItemsList != null && outpDoctorPrescMaster != null
                && outpDoctorPrescItemsList.size() > 0
                && outpDoctorPrescItemsList.toString().length() > 0 && outpDoctorPrescMaster.toString().length() > 0) {
            if (outpDoctorPrescMaster.getVerifyFlag() > 0) {
                return new ErrorTip(ExceptionHelpEnum.PRESC_CHECK_OLD);
            }
            if (outpDoctorPrescMasterMapper.updateVerifyFlag(visitDate, visitNo, verifyFlag, verifyRefuseCause)) {
                //审核通过的再做处方数据处理
                if (verifyFlag.equals(OrderConstant.PRESC_CHECK_OK)) {
                    String newPrescNo = DateUtil.getDays() + outpDoctorPrescMasterMapper.getNewPrescNo();
                    Timestamp sysdate = outpDoctorPrescMasterMapper.getSysdate();
                    PatientInfo patientInfo = patientInfoMapper.selectById(outpDoctorPrescMaster.getPatientId());
                    DrugPrescMaster drugPrescMaster = new DrugPrescMaster();
                    BeanUtils.copyProperties(outpDoctorPrescMaster, drugPrescMaster);
                    drugPrescMaster.setNamePhonetic(patientInfo.getNamePhonetic());
                    drugPrescMaster.setPrescDate(outpDoctorPrescMaster.getVisitDate());
                    drugPrescMaster.setPrescNo(outpDoctorPrescMaster.getVisitNo());
                    drugPrescMaster.setAge(String.valueOf(outpDoctorPrescMaster.getAge()));
                    drugPrescMaster.setPrescSource(OrderConstant.PRESC_SOURCE_OUTP);
                    drugPrescMaster.setRepetition(OrderConstant.PRESC_REPETITION);
                    drugPrescMaster.setStatus(OrderConstant.PRESC_STATUS_CHECK);
                    drugPrescMaster.setPrescArryNo(newPrescNo);
                    drugPrescMaster.setPrescribedBy(outpDoctorPrescMaster.getPrescriber());
                    drugPrescMaster.setEnteredBy(outpDoctorPrescMaster.getPrescriber());
                    drugPrescMaster.setCommitBy(outpDoctorPrescMaster.getPrescriber());
                    drugPrescMaster.setEnteredDatetime(outpDoctorPrescMaster.getVisitDate());
                    drugPrescMaster.setCommitDatetime(outpDoctorPrescMaster.getVisitDate());
                    //高新数据不全，待补充字段后从copy可以获取到
                    drugPrescMaster.setDispensary(outpDoctorPrescItemsList.get(0).getPerformedBy());
                    drugPrescMaster.setVerifyBy(oper);
                    drugPrescMaster.setVerifiedDatetime(sysdate);
//                DecimalFormat df = new DecimalFormat("#.##");
                    BigDecimal charges = new BigDecimal(0);
                    BigDecimal costs = new BigDecimal(0);
                    for (OutpDoctorPrescItems outpDoctorPrescItems : outpDoctorPrescItemsList) {
                        DrugPrescDetail drugPrescDetail = new DrugPrescDetail();
                        BeanUtils.copyProperties(outpDoctorPrescItems, drugPrescDetail);
                        drugPrescDetail.setPrescDate(outpDoctorPrescItems.getVisitDate());
                        drugPrescDetail.setPrescNo(outpDoctorPrescItems.getVisitNo());
                        drugPrescDetail.setPrescArryNo(newPrescNo);
                        drugPrescDetail.setPayments(outpDoctorPrescItems.getCharges());
                        drugPrescDetail.setDrugCode(outpDoctorPrescItems.getPhamCode());
                        drugPrescDetail.setDrugName(outpDoctorPrescItems.getPhamName());
                        drugPrescDetail.setDrugSpec(outpDoctorPrescItems.getPhamSpec());
                        drugPrescDetail.setQuantity(outpDoctorPrescItems.getAmount());
                        drugPrescDetail.setFreqDetail(outpDoctorPrescItems.getFrequency());
                        charges = charges.add(outpDoctorPrescItems.getCharges());
                        costs = costs.add(outpDoctorPrescItems.getCosts());
                        //两个字段暂不加入，需调用其它服务接口获取
//                    drugPrescDetail.setRetailPrice();
//                    drugPrescDetail.setRoundAmt();
                        if (drugPrescDetailMapper.insert(drugPrescDetail) == 0) {
                            throw new ExceptionHelp(ExceptionHelpEnum.PRESC_CHECK_SAVE_PRESC_DETAIL);
                        }
                    }
                    drugPrescMaster.setCosts(costs);
                    drugPrescMaster.setPayments(charges);
                    if (drugPrescMasterMapper.insert(drugPrescMaster) == 0) {
                        throw new ExceptionHelp(ExceptionHelpEnum.PRESC_CHECK_SAVE_PRESC_MASTER);
                    }
                }
            } else {
                return new ErrorTip(ExceptionHelpEnum.PRESC_CHECK_CHANGE_VERIFY_FLAG);
            }
        } else {
            return new ErrorTip(ExceptionHelpEnum.PRESC_CHECK_UNLL);
        }
        return new SuccessTip();
    }
}
